#include "red_msgparser.h"
#include "red_imsgent.h"
#include "red_msgentchat.h"
#include "red_msgenttextura.h"
#include <sstream>

using namespace std;

namespace red {
namespace protocolo {

MsgParser::MsgParser() :
	m_pMsgEnt(NULL),
	m_bEndMsg(false) {
}

MsgParser::~MsgParser() {
    this->finish_chunk_parsing();
}

IMsgEnt *MsgParser::parsear(const ustring &p_usChunck) {

	string t_sTemp = p_usChunck.data();
	unsigned int t_w = t_sTemp.find(">");

	this->parse_chunk(p_usChunck);
		
	return ((this->m_bEndMsg) && (t_w < string::npos))
		? this->m_pMsgEnt : NULL;
}

void MsgParser::on_start_document() {
}

void MsgParser::on_end_document() {
}

void MsgParser::on_start_element(const ustring &name, const AttributeList &attributes) {

	if (name.compare("Chat") == 0) {
		this->cargarMsgEntChat(attributes);
	} else if (name.compare("Textura") == 0) {
		this->cargarMsgEntTextura(attributes);
	}
}

void MsgParser::on_end_element(const ustring &name) {

	if (name.compare("Mensaje") == 0) {
		this->m_bEndMsg = true;
	}
}

void MsgParser::on_characters(const ustring &text) {
}

void MsgParser::on_comment(const ustring &text) {
}

void MsgParser::on_warning(const ustring &text) {
}

void MsgParser::on_error(const ustring &text) {
}

void MsgParser::on_fatal_error(const ustring &text) {
}

void MsgParser::cargarMsgEntChat(const AttributeList &attributes) {

	string t_sTexto;
	int t_iRemitente;
	istringstream t_iStream;

	for (AttributeList::const_iterator iter = attributes.begin();
		iter != attributes.end(); ++iter) {

		if (iter->name.compare("Texto") == 0) {
			t_sTexto = iter->value.data();
		} else if (iter->name.compare("Remitente") == 0) {
			t_iStream.str(iter->value.data());
			t_iStream >> t_iRemitente;
		}
	}

	this->m_pMsgEnt = new MsgEntChat(t_sTexto, t_iRemitente);
}

void MsgParser::cargarMsgEntTextura(const AttributeList &attributes) {

	string t_sBase64;

	for (AttributeList::const_iterator iter = attributes.begin();
		iter != attributes.end(); ++iter) {

		if (iter->name.compare("Base64") == 0) {
			t_sBase64 = iter->value.data();
		}
	}

	this->m_pMsgEnt = new MsgEntTextura(t_sBase64);
}

}
}
